package stack

import (
	. "jvm/typedef"
)

type Stack struct {
	capacity U4
	size     U4
	top      *node
}
type node struct {
	element interface{}
	next    *node
}

// public
func NewStack(capacity U4) *Stack {
	stack := &Stack{
		capacity: capacity,
		size:     0,
		top:      nil,
	}
	return stack
}

// ************************************************************************
// methods
func (self *Stack) Push(element interface{}) {
	if self.size >= self.capacity {
		panic("StackOverflowError at util.stack.stack.go.Push(element interface{})")
	}
	self.size++
	topNode := &node{
		element: element,
		next:    self.top,
	}
	self.top = topNode
}
func (self *Stack) Pop() interface{} {
	if self.IsEmpty() {
		panic("stack is empty!")
	}
	self.size--
	topNode := self.top
	self.top = topNode.next
	return topNode.element
}
func (self *Stack) Top() interface{} {
	return self.top.element
}

func (self *Stack) IsEmpty() bool {
	return self.size <= 0
}

// ************************************************************************
// getter
func (self *Stack) Size() U4 {
	return self.size
}

//************************************************************************
